/*
 * Flashlib - QB9 common Flash library
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.qb9.flashlib.utils
{
	/** Utility functions to operate on String instances. */
	public class StringUtil
	{
		/** Format a number with thousand separators. */
		public static function numberSeparator(num:Number, separator:String = ',', every:uint = 3) : String
		{
			var buffer:Array = [];
			var part:uint = Math.pow(10, every);
			
			while (Math.abs(num) >= part)
			{
				buffer.unshift(padLeft(num%part, every));
				num = Math.floor(num / part);
			}
			
			buffer.unshift(num);
			
			return buffer.join(separator);			
		}
		
		/** Fill a string with a cetain character so that its length is at least a given amount. */
		public static function padLeft(obj:Object, amount:uint=2, fill:String = '0') : String
		{
			var str:String = String(obj);
			while (str.length < amount)
				str = fill + str;
			return str;
		}
		
		private static var formatData:Object;
		
		/**
		 * Applies values to a string template
		 * 
		 * @param pattern The string template
		 * @param args The data to apply (multi-arguments or one object)
		 */

		public static function format(pattern:String, ...args) : String
		{
			formatData = args.length == 1 && typeof args[0] == 'object' ? args[0] : args;
			return pattern.replace(/\{(\S+?)\}/g, replace);
		}
		
		private static function replace(original:String, name:String, index:uint, pattern:String) : String
		{
			var data:Object = formatData;
			for each(var part:String in name.split('.'))
			{
				if (!data)
					break;
				data = data[part];
			}
			return data == null ? original : data.toString();
		}
		
		
		/**
		 * Removes trailing and leading spaces
		 * 
		 * @param text The string to trim
		 */
		public static function trim(text:String) : String
		{
			return text.replace(/^\s+|\s+$/g, '');
		}

		/**
		 * Removes trailing and leading spaces
		 * 
		 * @param text The string to trim
		 */
		public static function truncate(text:String, chars:uint, fill:String='...') : String
		{
			if (text.length > chars)
				text = text.slice(0, Math.max(chars - fill.length, 0)) + fill;
			return text;
		}		

		/**
		 * Makes a case insensitive string comparison
		 * 
		 * @param str One string
		 * @param str2 The other string
		 */
		public static function icompare(str:String, str2:String):Boolean
		{
			if (str === str2)
				return true;
				
			if (str === null || str2 === null)
				return false; 
			
			return str.toUpperCase() === str2.toUpperCase();
		}
			
		/**
		 * Capitalizes a string
		 * @param str A string
		 */
		public static function capitalize(str:String):String
		{
			return str.charAt(0).toUpperCase() + str.slice(1);
		}		
	}
}
